﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using ESOL.AutoUpdate.EsolWebService;
using System.IO;
using System.Net;

namespace ESOL.AutoUpdate
{
    public partial class frmUpdate : frmBaseForm
    {
        private string mProcesseName = "ESOL.WinUI";

        string clientVersion = string.Empty;//客户端版本号

        string serverVersion = string.Empty;//服务器版本号

        int mDownloadFilesCount = 0;

        string appPath = string.Empty;

        string mLocalFilePath = string.Empty;
        int mFilesCount = 0;

        Thread DownloadThread;      //下载线程
        Thread MonitorThread;       //监控线程

        bool mCompletedDownload = false;

        public frmUpdate()
        {
            InitializeComponent();
        }

        private void frmUpdate_Load(object sender, EventArgs e)
        {
            System.Diagnostics.Process[] wmsProcess = System.Diagnostics.Process.GetProcessesByName(mProcesseName);
            foreach (System.Diagnostics.Process process in wmsProcess)
            {
                process.Kill();
            }

            if ((DownloadThread != null && DownloadThread.ThreadState == ThreadState.Running) ||
                (MonitorThread != null && MonitorThread.ThreadState == ThreadState.Running))
            {
                MessageBox.Show("正在升级中，请不要重复点击！");
                return;
            }

            this.txtUpdateInfo.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            DownloadThread = new Thread(new ThreadStart(StartDownload));
            DownloadThread.Start();
        }

        public void StartDownload()
        {
            DeleSetUpdateInfo deleSetUpdateInfo = new DeleSetUpdateInfo(SetUpdateInfo);
            try
            {
                mLocalFilePath = Application.StartupPath; 
                if (Directory.Exists(mLocalFilePath) == false)
                {
                    Directory.CreateDirectory(mLocalFilePath);
                }
                //下载
                this.BeginInvoke(deleSetUpdateInfo, new object[] { "开始下载！" });
                MonitorThread = new Thread(new ThreadStart(MonitorDownload));
                MonitorThread.Start();
                using (EsolService service = new EsolService())
                {
                    string[] fileNames = service.GetUpdateFiles();
                    if (fileNames != null && fileNames.Length > 0)
                    {
                        for (int i = 0; i < fileNames.Length; i++)
                        {
                            using (WebClient client = new WebClient())
                            {
                                string fileName = fileNames[i].Substring(fileNames[i].LastIndexOf("\\") + 1);
                                string url = service.Url.Replace("/EsolService.asmx", "") + "/" + service.GetUpdateFolderName() + "/" + fileName;
                                string localFileName = mLocalFilePath + "\\" + fileName;
                                Uri u = new Uri(url);
                                if (fileName != "DataAccessConfiguration.config")
                                {
                                    //client.DownloadFileAsync(u, localFileName);
                                    client.DownloadFile(u, localFileName);
                                }
                                mDownloadFilesCount = i + 1;
                                this.BeginInvoke(deleSetUpdateInfo, new object[] { "已下载文件： " + fileName });
                            }
                        }
                    }
                    string configFileName = mLocalFilePath + "\\DataAccessConfiguration.config_";
                    ProcessingFile(configFileName);
                    configFileName = mLocalFilePath + "\\ESOL.WinUI.exe.config_";
                    ProcessingFile(configFileName);
                    configFileName = mLocalFilePath + "\\ESOL.WinUI.vshost.exe.config_";
                    ProcessingFile(configFileName);
                }
                Thread.Sleep(1000);
                mCompletedDownload = true;

                this.BeginInvoke(deleSetUpdateInfo, new object[] { "下载结束！" });

                this.BeginInvoke(deleSetUpdateInfo, new object[] { "更新成功！" });
            }
            catch (Exception ex)
            {
                this.BeginInvoke(deleSetUpdateInfo, new object[] { "更新失败！\n" + ex.Message });
            }
        }

        private void ProcessingFile(string configFileName)
        {
            if (File.Exists(configFileName))
            {
                string newConfigFileName = configFileName.Substring(0, configFileName.Length - 1);
                if (File.Exists(newConfigFileName))
                {
                    File.Delete(newConfigFileName);
                }
                File.Move(configFileName, newConfigFileName);
            }
        }

        public void MonitorDownload()
        {
            DelegateDownFile del = new DelegateDownFile(SetStatus);
            while (DownloadThread.ThreadState == ThreadState.Running)
            {
                if (mCompletedDownload == false)
                {
                    if (mFilesCount == 0)
                    {
                        using (EsolService service = new EsolService())
                        {
                            string[] fileNames = service.GetUpdateFiles();
                            mFilesCount = fileNames.Length;
                        }
                    }
                    this.BeginInvoke(del, new object[] { mFilesCount, mDownloadFilesCount });

                    Thread.Sleep(100);
                }
                else
                {
                    this.BeginInvoke(del, new object[] { mFilesCount, mFilesCount });
                    MonitorThread.Abort();
                }
            }
        }

        delegate void DeleSetUpdateInfo(string msg);
        delegate void DelegateDownFile(int totalFileCount, int downloadFilesCount);

        public void SetUpdateInfo(string msg)
        {
            if (string.IsNullOrEmpty(this.txtUpdateInfo.Text.Trim()))
            {
                txtUpdateInfo.Text += msg;
            }
            else
            {
                txtUpdateInfo.Text += "\r\n" + msg;
            }

            if (msg == "更新成功！")
            {
                if (DownloadThread != null)
                {
                    DownloadThread.Abort();
                }
                this.Close();
            }
        }

        public void SetStatus(int totalFileCount, int downloadFilesCount)
        {
            if (totalFileCount == 0)
            {
                pgBarStatus.Value = 100;
                lblPercent.Text = "100%";
                return;
            }

            pgBarStatus.Value = int.Parse((downloadFilesCount * 100 / totalFileCount).ToString());
            lblPercent.Text = pgBarStatus.Value.ToString() + "%"; 
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (DownloadThread != null && DownloadThread.ThreadState == ThreadState.Running)
            {
                DialogResult result = MessageBox.Show("程序正在升级中，强行退出可能造成程序错误，确认要退出吗？", "警告", MessageBoxButtons.OKCancel);
                if (result == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }

        private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
        {

        }
    }
}
